package com.weatherinczbackend;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Calendar;
import com.weatherinczbackend.exceptions.ComplexException;
import com.weatherinczbackend.exceptions.InternalErrorException;
import com.weatherinczbackend.exceptions.NullObjectException;
import net.sf.saxon.trans.XPathException;

/**
 * Main class called by servlet.
 * 
 * Function (2 possible use):
 * - Classic main called -
 * -- use 1 argument year, the number 61-99 or 0(00)-today
 * -- create weather.txt file with weather table from html of chmi page
 * -- convert weather.txt file to year.xml file by xquery parser
 * 
 * - Static methods called without main (use for servlet) -
 * -- use for calling from out, like servlet (our use)
 * -- need to use method initialize to get object FileWithWeatherParser
 * -- method getXmlAsString return String from actually created xml file
 * 
 * @author Bc. Michal Stava 255739 <255739@mail.muni.cz>
 */
public class Main {
    
    /**
     * Main method expecting one argument [int] year 00-today or 61-99
     * 
     * @param args 
     * @throws ComplexException if some internal exception occurs
     * @throws IOException input output exception when works with files
     */
    public static void main(String[] args) throws IOException, ComplexException {
            if(args.length > 1 || args.length < 1) throw new InternalErrorException("Too much or too low args, expected one (year).");
            FileWithWeatherParser fileWithWeatherParser = Main.initialize(args[0], "8859_2", "UTF-8");
            System.out.println(fileWithWeatherParser.xmlToString());
            System.out.println("XML file was created in xmls directory.");
    }
    
    /**
     * Create UrlToFileConverter and FileWithWeatherParser. 
     * Save and parse data from HTML page of CHMI to weather.txt
     * Parse weather.txt file to xml file with name of year (ex. 2005.xml)
     * 
     * @param year year which is same like argument of main method
     * @param inputCharset (inputCharset of data from HTML) 
     * @param outputCharset (outputCharset of file weather.txt)
     * -- for xml outputFile use UTF-8 charset automatic
     * 
     * @return FileWithWeatherParser object, created and prepared
     * 
     * @throws InternalErrorException when some internal error occurs
     * @throws IOException input output exception when works with files 
     */
    public static FileWithWeatherParser initialize(String year, String inputCharset, String outputCharset) throws InternalErrorException, IOException {
        year = Main.checkYearIsCorrect(year);
        String preparedUrl = "http://portal.chmi.cz/files/portal/docs/meteo/ok/uzt" + year + "_cs.html";
        
        URL url = new URL(preparedUrl);
        File file = new File("weather.txt");
        UrlToFileConvertor newUrlToFileParser = new UrlToFileConvertor(url, file, outputCharset, inputCharset);
        file = newUrlToFileParser.createFileFromUrl(true);

        if(year.startsWith("0") || year.startsWith("1")) year = "20" + year;
        else year = "19" + year;

        FileWithWeatherParser fileWithWeatherParser = new FileWithWeatherParser(file, year, outputCharset);
        try {
            fileWithWeatherParser.parseWeatherFile();
        } catch (XPathException ex) {
            throw new InternalErrorException("Xpath error.", ex);
        }
        return fileWithWeatherParser;
    }
    
    //This private method is only for test argument year and return correct format
    private static String checkYearIsCorrect(String year) throws InternalErrorException {
        if(year == null) throw new NullObjectException("Year can't be null.", "year");
        if(year.isEmpty() || year.length() > 2) throw new InternalErrorException("Year must be set and the possible values are [00 - today or 61-99]");
        
        //Get today year and month for maximal year whcih is allowed
        Calendar now = Calendar.getInstance();
        Integer todayYear = now.get(Calendar.YEAR);
        Integer todayMonth = now.get(Calendar.MONTH);
        if(todayMonth == 0) todayYear = todayYear -1;
        todayYear = Integer.valueOf(String.valueOf(todayYear).substring(2));
        
        Integer yearInteger = Integer.valueOf(year);
        if(yearInteger < 61 && yearInteger > todayYear) throw new InternalErrorException("Year must be set and the possible values are [00 - today or 61-99]");
        else if(yearInteger < 0 || yearInteger >99) throw new InternalErrorException("Year must be set and the possible values are [00 - today or 61-99]");
        
        if(year.length() == 1) year = "0" + year;
        return year;
    }
    
    /**
     * If xml is already created, return xmlFile in String.
     * 
     * @param fileWithWeatherParser
     * @return xmlFile in String
     * @throws InternalErrorException when some internal error occurs
     * @throws IOException input output exception when works with files
     */
    public static String getXmlAsString(FileWithWeatherParser fileWithWeatherParser) throws InternalErrorException, IOException {
        if(fileWithWeatherParser == null) throw new NullObjectException("File with weather parser must be already initialized!", "fileWithWeatherParser");
        return fileWithWeatherParser.xmlToString();
    }
}
